﻿using System;
using System.Linq;
using Dpy.Math.Algebra;

namespace Dpy.Math.Geometry.Geometry2D
{
    public class Vector2D : Vector
    {

        #region Properties

        public Vector Vector
        {
            get
            {
                return this as Vector;
            }
        }

        public double X
        {
            get
            {
                return this[0];
            }
        }

        public double Y
        {
            get
            {
                return this[1];
            }
        }

        #endregion


        #region Constructors

        public Vector2D()
            : this(0,0)
        {
        }

        public Vector2D(double x, double y)
            :base(new double[] {x, y})
        {
        }

        public Vector2D(Vector vector)
            : this(vector[0], vector[1])
        {
            if (vector.Dimension != 2)
            {
                throw new ArgumentException("Vector2D dimension must be 2!");
            }
        }

        #endregion


        #region Methods

        public new Vector2D Clone()
        {
            return new Vector2D(base.Clone());
        }

        public Vector2D RotateCounterClockwise(double angleInRadians)
        {
            double cos = System.Math.Cos(angleInRadians);
            double sin = System.Math.Sin(angleInRadians);

            return new Vector2D(
                this[0] * cos - this[1] * sin,
                this[0] * sin + this[1] * cos);
        }

        public Vector2D RotateClockWise(double angleInRadians)
        {
            double cos = System.Math.Cos(angleInRadians);
            double sin = System.Math.Sin(angleInRadians);

            return new Vector2D(
                this[0] * cos + this[1] * sin,
                (-this[0] * sin) + this[1] * cos);
        }

        #endregion


        #region Operators

        public static Vector2D operator *(Matrix m, Vector2D vector)
        {
            return new Vector2D(m * vector.Vector);
        }

        public static Vector2D operator *(Vector2D vector, Matrix m)
        {
            return new Vector2D(vector.Vector * m);
        }

        public static Vector2D operator *(double number, Vector2D vector)
        {
            return new Vector2D(number * vector.Vector);
        }

        public static Vector2D operator *(Vector2D vector, double number)
        {
            return number * vector;
        }

        public static Vector2D operator +(Vector2D a, Vector2D b)
        {
            return new Vector2D(a.Vector + b.Vector);
        }

        public static Vector2D operator -(Vector2D vector)
        {
            return new Vector2D(-vector.Vector);
        }

        public static Vector2D operator -(Vector2D a, Vector2D b)
        {
            return new Vector2D(a.Vector - b.Vector);
        }

        #endregion
    }
}
